package com.wg.io.sqlSession;

import com.wg.io.pojo.Configuration;
import com.wg.io.pojo.MappedStatement;

import java.lang.reflect.*;
import java.sql.SQLException;
import java.util.List;

/**
 * @author Mrwg
 * @date 2020/3/26 13:20
 * @description
 */
public class DefaultSqlSession implements SqlSession {
    private Configuration configuration;

    public DefaultSqlSession(Configuration configuration) {
        this.configuration = configuration;
    }

    private Executor simpleExcutor = new SimpleExecutor();

    @Override
    public <E> List<E> selectList(String statementId, Object... param) throws Exception {
        MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
        return simpleExcutor.query(configuration, mappedStatement, param);
    }
   /*增删改*/
    @Override
    public int insertSaveOrUpdate(String statementId, Object... params) throws Exception {
        MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
        return simpleExcutor.insertSaveOrUpdate(configuration, mappedStatement, params);
    }




    @Override
    public <T> T selectOne(String statementId, Object... params) throws Exception {
        List<Object> objects = selectList(statementId, params);
        if (objects.size() == 1) {
            return (T) objects.get(0);
        } else {
            throw new RuntimeException("返回结果有误");
        }
    }


    @Override
    public void close() throws SQLException {
        simpleExcutor.close();
    }

    /**
     * 使用jdk动态代理来为生成代理对象，并返回。
     *
     * @param mapperClass
     * @param <T>
     * @return
     */
    @Override
    public <T> T getMapper(Class<?> mapperClass) {
        Object o = Proxy.newProxyInstance(DefaultSqlSession.class.getClassLoader(), new Class[]{mapperClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                String methodNmae = method.getName();
                String className = method.getDeclaringClass().getName();
                String statementId = className + "." + methodNmae;

                Type retunrntype = method.getGenericReturnType();
                if (methodNmae.contains("find")) {
                    //判断返回值类型是否有泛型，有就是list
                    if (retunrntype instanceof ParameterizedType) {
                        List<Object> objects = selectList(statementId, args);
                        return objects;
                    } else {
                        return selectOne(statementId, args);
                    }
                } else {
                    //执行增删改
                    return insertSaveOrUpdate(statementId, args);
                }
            }
        });

        return (T) o;
    }


}
